<script setup>
import { watch, ref } from 'vue'
import DialogButton from './DialogButton.vue'
import { ElDialog } from 'element-plus';

const props = defineProps({
    visible: Boolean,
    title: String,
    width: {
        type: [String, Number],
        default: '60%'
    },
    titleBack: {
        type: Boolean,
        default: false
    },
    immediateClose: { // 关闭对话框后在 close 而非 closed 事件中执行emit('cancel')
        type: Boolean,
        default: false
    },
    confirmOnClosed: { // 在 closed 而非 close 事件中执行emit('confirm')，且确认时会无视 immediateClose 的 true 值
        type: Boolean,
        default: false
    },
    confirmButton: {
        type: [String, Boolean],
        default: '确定'
    },
    cancelButton: {
        type: [String, Boolean],
        default: '取消'
    }
})
const emit = defineEmits(['cancel', 'confirm'])

/**
 * el-dialog 的 destroy-on-close 并不会销毁对话框中外部插槽中的数据，那是在外部文件中管理的
 * 这里定义 dialogVisible 用于通过 closed事件 和 外部v-if 来销毁整个对话框，同时保留对话框的动画效果
 */
const dialogVisible = ref(props.visible)
watch(() => props.visible, (value) => value && (dialogVisible.value = true))

/**
 * 是否在 closed 事件中执行emit('confirm')
 */
const isClosedConfirm = ref(false)

function confirm() {
    if (!props.confirmOnClosed) {
        emit('confirm')
    } else {
        isClosedConfirm.value = true
    }
    close()
}

function close() {
    dialogVisible.value = false
}

function destroy(isClosedEvent) {
    if (isClosedEvent) {
        if (isClosedConfirm.value) {
            isClosedConfirm.value = false
            emit('confirm')
        }
        emit('cancel')
    }
    // 在 close 事件中，如果设置了立即关闭，则要保证关闭不是由确认函数触发的
    else if (props.immediateClose && (props.confirmOnClosed && !isClosedConfirm.value)) {
        emit('cancel')
    }
}
</script>

<template>
    <el-dialog
        :model-value="dialogVisible"
        :width="props.width"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        :align-center="true"
        @close="destroy(false)"
        @closed="destroy(true)">

        <template #header="{ titleId, titleClass }">
            <div :id="titleId" :class="titleClass">
                {{ props.title }}
            </div>
        </template>

        <slot></slot>

        <div class="dialog__bottom">
            <slot name="buttons">
                <DialogButton type="cancel" @click="close" v-if="props.cancelButton">{{ props.cancelButton }}</DialogButton>
                <DialogButton type="confirm" @click="confirm" v-if="props.confirmButton">{{ props.confirmButton }}</DialogButton>
            </slot>
        </div>

    </el-dialog>
</template>

<style scoped>
.title__icon--back {
    margin-right: 8px;
    transform: rotate(90deg);
    cursor: pointer;
    transition: opacity 0.1s;
}
.title__icon--back:hover {
    opacity: 0.8;
}
.dialog__bottom {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
}

</style>